﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;
using Param = ClassLibrary.Parameters.Values;

namespace ClassLibrary
{
    public class FTPUtility
    {
        /*public static string localPath_File_Log 
        { 
            get; set; 
        }*/

        #region PRIVATE

        private static Uri createURI(string serverFTP, string fileName)
        {
            try
            {
                string pathFTP = Path.Combine("ftp://", serverFTP);
                pathFTP = Path.Combine(pathFTP, fileName);
                pathFTP = pathFTP.Replace("\\", "//");
                Uri uri = new Uri(pathFTP);

                return uri;
            }
            catch (Exception e)
            {
                ErrorManager.WriteLog("FTPUtility", "createURI", e);
                return null;
            }
        }

        private static bool Exist_File_Or_Directory(string fullPath,  bool log)
        {
            FtpWebRequest request = null;

            try
            {
                bool RC = true;

                string leaf = PathUtility.getLeaf(fullPath);
                string parent = PathUtility.getParent(fullPath);
                string root = PathUtility.getRoot(fullPath);

                string serverFTP = parent == string.Empty ? root : parent;


                if (string.Empty != serverFTP && string.Empty != Param.Login && string.Empty != Param.MDP)
                {
                    Uri uri = createURI(serverFTP, string.Empty);

                    request = (FtpWebRequest)FtpWebRequest.Create(uri);

                    request.Method = WebRequestMethods.Ftp.ListDirectory;
                    request.Credentials = new NetworkCredential(Param.Login, Param.MDP);

                    FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                    StreamReader streamReader = new StreamReader(response.GetResponseStream());

                    List<string> directories = new List<string>();

                    string line = streamReader.ReadLine();
                    while (!string.IsNullOrEmpty(line))
                    {
                        directories.Add(PathUtility.getLeaf(line));
                        line = streamReader.ReadLine();
                    }

                    streamReader.Close();

                    if (string.Empty == parent || directories.Contains(leaf))
                        RC = true;
                    else RC = false;


                    request.Abort();
                }
                else
                {
                    RC = false;
                    throw new Exception("Invalid parameters");
                }

                return RC;
            }
            catch (Exception e)
            {
                ErrorManager.WriteLog("FTPUtility", "Exist_File_Or_Directory", e);
                if (null != request)
                    request.Abort();

                return false;
            }
        }

        //private static bool Exist_File_Or_Directory(string FtpPath, string dir_or_file_name, bool log)
        //{
        //    FtpWebRequest request = null;

        //    try
        //    {
        //        bool RC = true;

        //        //Connection test
        //        string serverFTP = FtpPath;

        //        if (string.Empty != serverFTP && string.Empty != Param.Login && string.Empty != Param.MDP)
        //        {
        //            Uri uri = createURI(serverFTP, string.Empty);

        //            request = (FtpWebRequest)FtpWebRequest.Create(uri);

        //            request.Method = WebRequestMethods.Ftp.ListDirectory;
        //            request.Credentials = new NetworkCredential(Param.Login, Param.MDP);
                    
        //            FtpWebResponse response = (FtpWebResponse)request.GetResponse();

        //            StreamReader streamReader = new StreamReader(response.GetResponseStream());

        //            List<string> directories = new List<string>();

        //            string line = streamReader.ReadLine();
        //            while (!string.IsNullOrEmpty(line))
        //            {
        //                directories.Add(Path.GetFileName(line));
        //                line = streamReader.ReadLine();
        //            }

        //            streamReader.Close();

        //            dir_or_file_name = dir_or_file_name.Replace("\\", "/");
        //            if (string.Empty == dir_or_file_name || directories.Contains(dir_or_file_name))
        //                RC = true;
        //            else RC = false;


        //            request.Abort();
        //        }
        //        else
        //        {
        //            RC = false;
        //            throw new Exception("Invalid parameters");
        //        }

        //        return RC;
        //    }
        //    catch (Exception e)
        //    {
        //        ErrorManager.WriteLog("FTPUtility", "Exist_File_Or_Directory", e);
        //        if (null != request)
        //            request.Abort();

        //        return false;
        //    }
        //}

        #endregion

        public static bool ConnectionTest( bool log)
        {
            return Exist_File_Or_Directory(Param.FTPServer, log);
        }

        public static bool MakeDirectory(string relativePath)
        {
            FtpWebRequest request = null;

            try
            {
                bool RC = true;

                //Connection test
                string serverFTP = Path.Combine(Param.FTPServer, relativePath);

                if (string.Empty != serverFTP && string.Empty != Param.Login && string.Empty != Param.MDP)
                {
                    Uri uri = createURI(serverFTP, string.Empty);

                    request = (FtpWebRequest)FtpWebRequest.Create(uri);

                    request.Method = WebRequestMethods.Ftp.MakeDirectory;
                    request.Credentials = new NetworkCredential(Param.Login, Param.MDP);

                    FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                    request.Abort();

                    RC = true;
                }
                else
                {
                    RC = false;
                    throw new Exception("Invalid parameters");
                }

                return RC;
            }
            catch (Exception e)
            {
                ErrorManager.WriteLog("FTPUtility", "Exist_File_Or_Directory", e);
                if (null != request)
                    request.Abort();

                return false;
            }
        }

        public static bool ExistDirectory(string Path, /*string dirName,*/ bool log)
        {
            return Exist_File_Or_Directory(Path, log);
        }

        public static bool ExistFile(string Path, /*string fileName,*/ bool log)
        {
            return Exist_File_Or_Directory(Path, log);
        }

        public static bool DownLoadImg(string relative_server_File_Path, string local_FileDest_path)
        {
            try
            {
                // Get the object used to communicate with the server.
                Uri uri = createURI(Param.FTPServer, relative_server_File_Path);

                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
                request.Method = WebRequestMethods.Ftp.DownloadFile;
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(Param.Login, Param.MDP);

                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                Stream responseStream = response.GetResponseStream();

                long cl = response.ContentLength;
                int bufferSize = 4096;  //Image file cannot be greater than 40 Kb
                int readCount = 0;
                byte[] buffer = new byte[bufferSize];
                FileStream outputStream = new FileStream(local_FileDest_path, FileMode.Create);
                readCount = responseStream.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                    outputStream.Write(buffer, 0, readCount);
                    readCount = responseStream.Read(buffer, 0, bufferSize);
                }
                response.Close();
                outputStream.Close();
                responseStream.Close();

                //Save in tmp
                /*string tmp_Dir_Path = System.IO.Path.GetTempPath() + Application.ProductName;
                string tmp_File_Path = Path.Combine(tmp_Dir_Path, Path.GetFileName(server_File_Path));*/

                /*if (!System.IO.Directory.Exists(tmp_Dir_Path))
                    System.IO.Directory.CreateDirectory(tmp_Dir_Path);*/

                /*StreamWriter sr = new StreamWriter(local_FileDest_path);
                sr.Write(memStream);
                sr.Close();*/

                if (File.Exists(local_FileDest_path))
                    return true;
                else
                    throw new Exception("Download failed : " + relative_server_File_Path);
            }
            catch (Exception e)
            {
                //local_FileInfo = new FileInfo(string.Empty);
                ErrorManager.WriteLog("FTPUtility", "DownLoad", e);
                return false;
            }
        }

        public static bool DownLoad( string relative_server_File_Path, string local_FileDest_path)
        {
            try
            {
                // Get the object used to communicate with the server.
                Uri uri = createURI(Param.FTPServer, relative_server_File_Path);

                FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
                request.Method = WebRequestMethods.Ftp.DownloadFile;
                request.Credentials = new NetworkCredential(Param.Login, Param.MDP);

                FtpWebResponse response = (FtpWebResponse)request.GetResponse();

                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8);
                string file = reader.ReadToEnd();
                reader.Close();
                response.Close();

                //Save in tmp
                /*string tmp_Dir_Path = System.IO.Path.GetTempPath() + Application.ProductName;
                string tmp_File_Path = Path.Combine(tmp_Dir_Path, Path.GetFileName(server_File_Path));*/

                /*if (!System.IO.Directory.Exists(tmp_Dir_Path))
                    System.IO.Directory.CreateDirectory(tmp_Dir_Path);*/

                StreamWriter sr = new StreamWriter(local_FileDest_path);
                sr.Write(file);
                sr.Close();

                if (File.Exists(local_FileDest_path))
                    return true;
                else
                    throw new Exception("Download failed : " + relative_server_File_Path);
            }
            catch (Exception e)
            {
                //local_FileInfo = new FileInfo(string.Empty);
                ErrorManager.WriteLog("FTPUtility", "DownLoad", e);
                return false;
            }
        }

        public static bool Upload( string local_File_Path, string FTPPath, string fileName)
        {
            try
            {
                Uri uri = createURI(Param.FTPServer, Path.Combine(FTPPath,fileName));

                FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(uri);

                request.Method = WebRequestMethods.Ftp.UploadFile;
                request.Credentials = new NetworkCredential(Param.Login, Param.MDP);
                request.UsePassive = true;
                request.UseBinary = true;
                request.KeepAlive = false;

                //Load the file
                FileStream stream = File.OpenRead(local_File_Path);
                byte[] buffer = new byte[stream.Length];

                stream.Read(buffer, 0, buffer.Length);
                stream.Close();

                //Upload file
                Stream reqStream = request.GetRequestStream();
                reqStream.Write(buffer, 0, buffer.Length);
                reqStream.Close();

                string path = Path.Combine(Param.FTPServer, Path.Combine(FTPPath, fileName));
                bool RC = ExistFile(path, false);
                if (!RC)
                    throw new Exception("Upload Failed  : " + Path.Combine(FTPPath,fileName));

                return RC;
            }
            catch (Exception e)
            {
                ErrorManager.WriteLog("Services.cs", "FTP_UploadFile", e);
                return false;
            }
        }

        /*public static bool FTP_DeleteFile(Parametres.Values param, FileInfo file)
        {
            // The serverUri parameter should use the ftp:// scheme.
            // It contains the name of the server file that is to be deleted.
            // Example: ftp://contoso.com/someFile.txt.
            // 

            Uri serverUri = createURI(param.FTPServer, file.Name);
            if (serverUri.Scheme != Uri.UriSchemeFtp)
            {
                return false;
            }
            // Get the object used to communicate with the server.
            FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
            request.Method = WebRequestMethods.Ftp.DeleteFile;

            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            Console.WriteLine("Delete status: {0}", response.StatusDescription);
            response.Close();
            return true;
        }*/

        //public static bool FTP_UploadFile(Parametres.Values param, FileInfo inputFile)
        //{
        //    try
        //    {
        //        //Initialisation de l'accès FTP
        //        string pathFTP = Path.Combine("ftp://", param.FTPServer);
        //        pathFTP = Path.Combine(pathFTP, inputFile.Name);
        //        pathFTP = pathFTP.Replace("\\", "//");
        //        Uri uri = new Uri(pathFTP);

        //        FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(uri);

        //        request.Method = WebRequestMethods.Ftp.UploadFile;
        //        request.Credentials = new NetworkCredential(param.login, param.mdp);
        //        request.UsePassive = true;
        //        request.UseBinary = true;
        //        request.KeepAlive = false;

        //        //Load the file
        //        FileStream stream = File.OpenRead(inputFile.FullName);
        //        byte[] buffer = new byte[stream.Length];

        //        stream.Read(buffer, 0, buffer.Length);
        //        stream.Close();

        //        //Upload file
        //        Stream reqStream = request.GetRequestStream();
        //        reqStream.Write(buffer, 0, buffer.Length);
        //        reqStream.Close();


        //        return true;
        //    }
        //    catch (Exception e)
        //    {
        //        ErrorManager.Write("Services.cs", "FTP_UploadFile", e);
        //        return false;
        //    }
        //}

        /*public static bool URL_LoadImage(string url, out Bitmap image)
        {
            bool RC = true;
            url = url.Replace("\\", "//");
            HttpWebRequest wreq;
            HttpWebResponse wresp;
            Stream mystream;

            image = null;
            mystream = null;
            wresp = null;
            try
            {
                wreq = (HttpWebRequest)WebRequest.Create(url);
                wreq.AllowWriteStreamBuffering = true;

                wresp = (HttpWebResponse)wreq.GetResponse();

                if ((mystream = wresp.GetResponseStream()) != null)
                    image = new Bitmap(mystream);
                RC = true;
            }
            catch (Exception e)
            {
                ErrorManager.Write("Service.cs", "URL_LoadIMage", e);
                RC = false;
            }
            finally
            {
                if (mystream != null)
                    mystream.Close();

                if (wresp != null)
                    wresp.Close();
            }

            return RC;
        }*/

        /*public static bool FTP_SaveDataSet(string serverFTP, string login, string mdp)
        {
            try
            {
                //Initialisation de l'accès FTP
                string pathFTP = Path.Combine("ftp://", serverFTP);
                pathFTP = Path.Combine(pathFTP, "SaveDataSet");
                pathFTP = pathFTP.Replace("\\", "//");
                Uri uri = new Uri(pathFTP);
                FtpWebRequest ftpclientRequest = (FtpWebRequest)FtpWebRequest.Create(uri);


                ftpclientRequest.Credentials = new NetworkCredential(login, mdp);
                ftpclientRequest.UsePassive = true;
                ftpclientRequest.UseBinary = true;
                ftpclientRequest.KeepAlive = false;



                ftpclientRequest.Method = WebRequestMethods.Ftp.ListDirectory;
                WebResponse response = ftpclientRequest.GetResponse();
                StreamReader sr = new StreamReader(response.GetResponseStream(), System.Text.Encoding.ASCII);
                string Datastring = sr.ReadToEnd();
                response.Close();


                string[] list = GetList(Datastring);


                return true;
            }
            catch (Exception e)
            {
                ErrorManager.Write("Services.cs", "FTP_SaveDataSet", e);
                return false;
            }

        }*/

        /*public static bool FTP_CreateDirectory(Parametres.Values param, string directory)
        {
            try
            {
                //Initialisation de l'accès FTP
                string pathFTP = Path.Combine("ftp://", param.FTPServer);
                pathFTP = Path.Combine(pathFTP, directory);
                pathFTP = pathFTP.Replace("\\", "//");


                WebRequest request = WebRequest.Create(pathFTP);
                request.Method = WebRequestMethods.Ftp.MakeDirectory;
                request.Credentials = new NetworkCredential(param.login, param.mdp);
                WebResponse rep = request.GetResponse();

                return true;
            }
            catch (Exception e)
            {
                ErrorManager.Write("Services.cs", "FTP_SaveDataSet", e);
                return false;
            }
        }*/

        //-------------------------------------------------------------------------


        //Lecture des fichiers présents sur le serveur
        //-------------------------------------------------------------------------
        /*public struct FileStruct
        {
            public string Flags;
            public string Owner;
            public string Group;
            public bool IsDirectory;
            public DateTime CreateTime;
            public string Name;
        }*/

        /*public enum FileListStyle
        {
            UnixStyle,
            WindowsStyle,
            Unknown
        }*/

        /*private static string[] GetList(string datastring)
        {
            List<string> myListArray = new List<string>();
            string[] dataRecords = datastring.Split('\n');
            //FileListStyle _directoryListStyle = FileListStyle.WindowsStyle;// GuessFileListStyle(dataRecords);
            foreach (string s in dataRecords)
            {
                string tmp = s.Replace("\r", "");
                tmp = tmp.Replace("/.", "");
                tmp = tmp.Replace("/..", "");
                string ext = Path.GetExtension(tmp);
                string name = Path.GetFileName(tmp);

                //FileStruct f = new FileStruct();
                //f = ParseFileStructFromWindowsStyleRecord(s);
                //f.

                if (ext == ".js")
                {
                    myListArray.Add(name);
                }
            }
            return myListArray.ToArray();
        }*/

        /*private static FileStruct ParseFileStructFromWindowsStyleRecord(string Record)
        {
            ///Assuming the record style as 
            /// 02-03-04  07:46PM       <DIR>          Append
            FileStruct f = new FileStruct();
            string processstr = Record.Trim();
            string dateStr = processstr.Substring(0, 8);
            processstr = (processstr.Substring(8, processstr.Length - 8)).Trim();
            string timeStr = processstr.Substring(0, 7);
            processstr = (processstr.Substring(7, processstr.Length - 7)).Trim();
            f.CreateTime = DateTime.Parse(dateStr + " " + timeStr);

            if (processstr.Substring(0, 5) == "<DIR>")
            {
                f.IsDirectory = true;
                processstr = (processstr.Substring(5, processstr.Length - 5)).Trim();
            }
            else
            {
                string[] strs = processstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                processstr = strs[1].Trim();
                f.IsDirectory = false;
            }
            f.Name = processstr;  //Rest is name   
            return f;
        }*/

        /*public static FileListStyle GuessFileListStyle(string[] recordList)
        {
         foreach (string s in recordList)
         {
          if(s.Length > 10 
           && Regex.IsMatch(s.Substring(0,10),"(-|d)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)"))
          {
           return FileListStyle.UnixStyle;
          }      
          else if (s.Length > 8 
           && Regex.IsMatch(s.Substring(0, 8),  "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]"))
          {
           return FileListStyle.WindowsStyle;
          }   
         }
         return FileListStyle.Unknown;
        }*/

        /*private FileStruct ParseFileStructFromUnixStyleRecord(string Record)
        {
         ///Assuming record style as
         /// dr-xr-xr-x   1 owner    group               0 Nov 25  2002 bussys
         FileStruct f= new FileStruct();   
         string processstr = Record.Trim();        
         f.Flags = processstr.Substring(0,9);
         f.IsDirectory = (f.Flags[0] == 'd');  
         processstr =  (processstr.Substring(11)).Trim();
         _cutSubstringFromStringWithTrim(ref processstr,' ',0);   //skip one part
         f.Owner = _cutSubstringFromStringWithTrim(ref processstr,' ',0);
         f.Group = _cutSubstringFromStringWithTrim(ref processstr,' ',0);
         _cutSubstringFromStringWithTrim(ref processstr,' ',0);   //skip one part
         f.CreateTime = DateTime.Parse(_cutSubstringFromStringWithTrim(ref processstr,' ',8));     
         f.Name =  processstr;   //Rest of the part is name
         return f;
        }*/

        /*private string _cutSubstringFromStringWithTrim(ref string s, char c, int startIndex)
        {
               int pos1 = s.IndexOf(c, startIndex);
              string retString = s.Substring(0,pos1);
              s = (s.Substring(pos1)).Trim();
              return retString;
          }*/

        //---------------------------------------

        //public static void setInfoFont(TextBox textBox, string text)
        //{
        //    textBox.Text = text;
        //    textBox.ForeColor = Color.DimGray;
        //    textBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        //}

        //public static void setText(TextBox textBox, string text)
        //{
        //    if (string.Compare(textBox.Text, text, false) == 0)
        //    {
        //        textBox.Text = string.Empty;
        //        textBox.ForeColor = Color.Black;
        //        textBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        //    }
        //    else if (string.Compare(textBox.Text, string.Empty, false) == 0)
        //    {
        //        textBox.Text = text;
        //        textBox.ForeColor = Color.DimGray;
        //        textBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        //    }
        //}

        //public static void setRegularFont(TextBox textBox, string text)
        //{
        //    textBox.Text = text;
        //    textBox.ForeColor = Color.Black;
        //    textBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        //}

        //-----------------------------------------
        
    }
}
